d->shared_info->n_vcpu = num_online_cpus();
for ( i = 1; i < d->shared_info->n_vcpu; i++ )
- (void)alloc_vcpu(d, i);
+ (void)alloc_vcpu(d, i, i % num_online_cpus());
/* Set up monitor table */
update_pagetables(v);
case DOM0_MAX_VCPUS:
{
struct domain *d;
- unsigned int i, max = op->u.max_vcpus.max;
+ unsigned int i, max = op->u.max_vcpus.max, cpu;
ret = -EINVAL;
if ( max > MAX_VIRT_CPUS )
ret = -ENOMEM;
for ( i = 0; i < max; i++ )
- if ( (d->vcpu[i] == NULL) && (alloc_vcpu(d, i) == NULL) )
- goto maxvcpu_out;
+ {
+ if ( d->vcpu[i] == NULL )
+ {
+ cpu = (d->vcpu[i-1]->processor + 1) % num_online_cpus();
+ if ( alloc_vcpu(d, i, cpu) == NULL )
+ goto maxvcpu_out;
+ }
+ }
ret = 0;
if ( (d = alloc_domain()) == NULL )
return NULL;
- v = d->vcpu[0];
+ d->domain_id = dom_id;
atomic_set(&d->refcnt, 1);
- atomic_set(&v->pausecnt, 0);
-
- d->domain_id = dom_id;
- v->processor = cpu;
spin_lock_init(&d->big_lock);
-
spin_lock_init(&d->page_alloc_lock);
INIT_LIST_HEAD(&d->page_list);
INIT_LIST_HEAD(&d->xenpage_list);
return NULL;
}
+ if ( (v = alloc_vcpu(d, 0, cpu)) == NULL )
+ {
+ grant_table_destroy(d);
+ evtchn_destroy(d);
+ free_domain(d);
+ return NULL;
+ }
+
arch_do_createdomain(v);
- sched_add_domain(v);
-
if ( !is_idle_task(d) )
{
write_lock(&domlist_lock);
if ( (rc = arch_set_info_guest(v, ctxt)) != 0 )
return rc;
- sched_add_domain(v);
-
return rc;
}
xfree(d);
}
-struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id)
+struct vcpu *alloc_vcpu(
+ struct domain *d, unsigned int vcpu_id, unsigned int cpu_id)
{
struct vcpu *v;
v->domain = d;
v->vcpu_id = vcpu_id;
+ v->processor = cpu_id;
atomic_set(&v->pausecnt, 0);
v->cpumap = CPUMAP_RUNANYWHERE;
return NULL;
}
- if ( vcpu_id == 0 )
- return v;
+ sched_add_domain(v);
- v->vcpu_info = &d->shared_info->vcpu_data[vcpu_id];
-
- d->vcpu[v->vcpu_id-1]->next_in_list = v;
-
- v->processor = (d->vcpu[0]->processor + 1) % num_online_cpus();
- if ( test_bit(_VCPUF_cpu_pinned, &d->vcpu[0]->vcpu_flags) )
- set_bit(_VCPUF_cpu_pinned, &v->vcpu_flags);
-
- set_bit(_VCPUF_down, &v->vcpu_flags);
+ if ( vcpu_id != 0 )
+ {
+ v->vcpu_info = &d->shared_info->vcpu_data[vcpu_id];
+ d->vcpu[v->vcpu_id-1]->next_in_list = v;
+ set_bit(_VCPUF_down, &v->vcpu_flags);
+ }
return v;
}
{
struct domain *d;
- if ( (d = xmalloc(struct domain)) == NULL )
- return NULL;
-
- memset(d, 0, sizeof(*d));
-
- if ( alloc_vcpu(d, 0) == NULL )
- goto out;
+ if ( (d = xmalloc(struct domain)) != NULL )
+ memset(d, 0, sizeof(*d));
return d;
-
- out:
- xfree(d);
- return NULL;
}
/*
#define IDLE_DOMAIN_ID (0x7FFFU)
#define is_idle_task(_d) (test_bit(_DOMF_idle_domain, &(_d)->domain_flags))
-struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id);
+struct vcpu *alloc_vcpu(
+ struct domain *d, unsigned int vcpu_id, unsigned int cpu_id);
struct domain *alloc_domain(void);
void free_domain(struct domain *d);